package com.example.tourism.Controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.tourism.Mapper.scenicspot.scenicspotMapper;
import com.example.tourism.Service.routeService;
import com.example.tourism.bean.scenicspot.scenicspot;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@CrossOrigin(origins = "*")
public class routingController {  //TODO 路径规划的控制器，只有路径规划相关功能
    @Autowired
    private scenicspotMapper spotsMapper;
    @Autowired
    private routeService routeService;

    /**
     * 路径规划请求，是旅游景点路径规划
     * @param requestData
     * @return
     */
    @PostMapping("/routing")
    public ResponseEntity<Map<String, Object>> routingCal(@RequestBody Map<String, Object> requestData)  {
        List<Long> idList = (List<Long>) requestData.get("idList");  //获取的景点的id列表
        String ridingPrefer = (String) requestData.get("ridingPrefer");  //骑行偏好  可选值： 0 普通自行车 ； 1 电动自行车
        boolean timePrefer = (boolean) requestData.get("timePrefer");  //true表示喜欢短时间，false表示喜欢短路程，true代表下面limit是时间，否则为路程
        int tempLimit = (int) requestData.get("Limit");  //获取规划的限制需求最大值，如果时间没需求则为-1
        int Limit = tempLimit ==-1 ? Integer.MAX_VALUE : tempLimit;  //如果没需求则-1，暂时设置为整形最大

        QueryWrapper<scenicspot> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", idList);
        String[] idArray = new String[idList.size()];
        for(int i=0;i<idList.size();++i){
            idArray[i] = String.valueOf(idList.get(i));
        }
        if(idList.size()!=0) {
            String orderByClause = "FIELD(id, " + String.join(",", idArray) + ")";
            queryWrapper.orderByAsc(orderByClause);  //按照idList规则进行升序排列
        }
        List<scenicspot> spotsList = spotsMapper.selectList(queryWrapper); //获取id在idList中的数据
        try {
            routeService.run(spotsList, ridingPrefer, Limit, timePrefer);
        }catch (Exception e){
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);  //计算失败，出错   null值代表出错
        }
        if(routeService.getCnt()==0){  //即表示在当前条件下无法满足
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new HashMap<>());  //计算失败，出错   HashMap占位，无实际意义，表示当前条件下无法计算，即顾客选择的时间所有情况都不满足
        }
        int[][] driveDistance , driveTime;
        int[][] rideDistance , rideTime;
        int[][] walkDistance , walkTime;
        List<Integer> tourIdList , tourTypeList;
        driveDistance = routeService.getDriveDistance();
        driveTime = routeService.getDriveTime();
        rideDistance = routeService.getRideDistance();
        rideTime = routeService.getRideTime();
        walkDistance = routeService.getWalkDistance();
        walkTime= routeService.getWalkTime();

        tourIdList = routeService.getTourIdList(timePrefer);  //获得的id实际上是数组的索引值
        tourTypeList = routeService.getTourTypeList(timePrefer);  //出行方式，索引值是按照tourList的索引值来的

        Map<String, Object> tourData = new HashMap<>();  //封装在Map里面进行返回
        tourData.put("driveDistance",driveDistance);  //放入 开车 距离数组
        tourData.put("driveTime",driveTime);  //放入 开车 时间数组
        tourData.put("rideDistance",rideDistance); //放入 骑行 距离数组
        tourData.put("rideTime",rideTime);  //放入 骑行 时间数组
        tourData.put("walkDistance",walkDistance); //放入 走路 距离数组
        tourData.put("walkTime",walkTime); //放入 走路 时间数组
        tourData.put("tourIdList",tourIdList); // 放入 最佳 的 行驶路线
        tourData.put("tourTypeList",tourTypeList); //放入 最佳 行驶路线 对应的 出行方式，此List比行驶路线的List少一位，因为a->b对应一个最佳方式

        return ResponseEntity.ok(tourData);  //返回计算好的所有内容。即上述tourData填入的内容
    }

    /**
     * 路径规划请求，纯路径规划
     * @param requestData
     * @return
     */
    @PostMapping("/routingOfRoute")
    public ResponseEntity<Map<String, Object>> routingCalForRoute(@RequestBody Map<String, Object> requestData)  {
        List<Long> idList = (List<Long>) requestData.get("idList");  //获取的景点的id列表
        String ridingPrefer = (String) requestData.get("ridingPrefer");  //骑行偏好  可选值： 0 普通自行车 ； 1 电动自行车
        boolean timePrefer = (boolean) requestData.get("timePrefer");  //true表示喜欢短时间，false表示喜欢短路程，true代表下面limit是时间，否则为路程
        int tempLimit = (int) requestData.get("Limit");  //获取规划的限制需求最大值，如果时间没需求则为-1
        int Limit = tempLimit ==-1 ? Integer.MAX_VALUE : tempLimit;  //如果没需求则-1，暂时设置为整形最大

        QueryWrapper<scenicspot> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", idList);
        String[] idArray = new String[idList.size()];
        for(int i=0;i<idList.size();++i){
            idArray[i] = String.valueOf(idList.get(i));
        }
        String orderByClause = "FIELD(id, " + String.join(",",idArray) + ")";
        queryWrapper.orderByAsc(orderByClause);  //按照idList规则进行升序排列
        List<scenicspot> spotsList = spotsMapper.selectList(queryWrapper); //获取id在idList中的数据
        try {
            routeService.run(spotsList, ridingPrefer, Limit, timePrefer);
        }catch (Exception e){
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);  //计算失败，出错   null值代表出错
        }
        if(routeService.getCnt()==0){  //即表示在当前条件下无法满足
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new HashMap<>());  //计算失败，出错   HashMap占位，无实际意义，表示当前条件下无法计算，即顾客选择的时间所有情况都不满足
        }
        int[][] driveDistance , driveTime;
        int[][] rideDistance , rideTime;
        int[][] walkDistance , walkTime;
        List<Integer> tourIdList , tourTypeList;
        driveDistance = routeService.getDriveDistance();
        driveTime = routeService.getDriveTime();
        rideDistance = routeService.getRideDistance();
        rideTime = routeService.getRideTime();
        walkDistance = routeService.getWalkDistance();
        walkTime= routeService.getWalkTime();

        tourIdList = routeService.getTourIdList(timePrefer);  //获得的id实际上是数组的索引值
        tourTypeList = routeService.getTourTypeList(timePrefer);  //出行方式，索引值是按照tourList的索引值来的

        Map<String, Object> tourData = new HashMap<>();  //封装在Map里面进行返回
        tourData.put("driveDistance",driveDistance);  //放入 开车 距离数组
        tourData.put("driveTime",driveTime);  //放入 开车 时间数组
        tourData.put("rideDistance",rideDistance); //放入 骑行 距离数组
        tourData.put("rideTime",rideTime);  //放入 骑行 时间数组
        tourData.put("walkDistance",walkDistance); //放入 走路 距离数组
        tourData.put("walkTime",walkTime); //放入 走路 时间数组
        tourData.put("tourIdList",tourIdList); // 放入 最佳 的 行驶路线
        tourData.put("tourTypeList",tourTypeList); //放入 最佳 行驶路线 对应的 出行方式，此List比行驶路线的List少一位，因为a->b对应一个最佳方式

        return ResponseEntity.ok(tourData);  //返回计算好的所有内容。即上述tourData填入的内容
    }

}
